﻿using Inovout.Descriptors;
using Inovout.Models;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace Inovout.Web.Mvc
{
    public static class EntityExtensions
    {
        public static MvcHtmlString Pager(this HtmlHelper htmlHelper, IDataObjectPagedSet set, string linkFormat, IDictionary<string, object> htmlAttributes = null)
        {
            return htmlHelper.Pager(set.PageSize, set.PageIndex, set.ResultCount, linkFormat, htmlAttributes);
        }
        public static MvcHtmlString Pager(this HtmlHelper htmlHelper, int pageSize, int pageIndex, int totalCount, string linkFormat, IDictionary<string, object> htmlAttributes = null)
        {
            TagBuilder pagerTagBuilder = new TagBuilder("div");
            int totalPage = (int)(totalCount / pageSize);
            if (totalCount % pageSize >= 1)
            {
                totalPage++;
            }
            StringBuilder pagerLinkBuilder = new StringBuilder();
            int startPageIndex = 1;
            int endPageIndex = 10;
            //总页数小于10
            if (totalPage < 10)
            {
                startPageIndex = 1;
                endPageIndex = totalPage;
                while (startPageIndex <= endPageIndex)
                {
                    if (startPageIndex.Equals(pageIndex))
                    {
                        pagerLinkBuilder.AppendFormat("<span class=\"current\">{0}</span>", pageIndex.ToString());
                    }
                    else
                    {
                        pagerLinkBuilder.AppendFormat("<a href=\"{0}\">{1}</a>", string.Format(linkFormat, startPageIndex.ToString()), startPageIndex.ToString());
                    }
                    startPageIndex++;
                }
            }

            //总页数大于10
            if (totalPage > 10)
            {
                if (pageIndex <= 5)
                {
                    startPageIndex = 1;
                    endPageIndex = 10;
                    while (startPageIndex < endPageIndex)
                    {
                        if (startPageIndex.Equals(pageIndex))
                        {
                            pagerLinkBuilder.AppendFormat("<span class=\"current\">{0}</span>", pageIndex.ToString());
                        }
                        else
                        {
                            pagerLinkBuilder.AppendFormat("<a href=\"{0}\">{1}</a>", string.Format(linkFormat, startPageIndex.ToString()), startPageIndex.ToString());
                        }
                        startPageIndex++;
                    }

                    while (startPageIndex <= totalPage)
                    {
                        pagerLinkBuilder.AppendFormat("<a href=\"{0}\">{1}</a>", string.Format(linkFormat, startPageIndex.ToString()), startPageIndex.ToString());
                        startPageIndex = startPageIndex + 10;
                    }

                    int remainder = totalPage % 10;
                    if (remainder != 0)
                    {
                        pagerLinkBuilder.Append("<span>···</span>");
                        pagerLinkBuilder.AppendFormat("<a href=\"{0}\">{1}</a>", string.Format(linkFormat, totalPage.ToString()), totalPage.ToString());

                    }

                }

                if (pageIndex > 5 && pageIndex <= totalPage - 5)
                {
                    startPageIndex = pageIndex - 4;
                    endPageIndex = pageIndex + 5;
                    while (startPageIndex < endPageIndex)
                    {
                        if (startPageIndex.Equals(pageIndex))
                        {
                            pagerLinkBuilder.AppendFormat("<span class=\"current\">{0}</span>", pageIndex.ToString());
                        }
                        else
                        {
                            pagerLinkBuilder.AppendFormat("<a href=\"{0}\">{1}</a>", string.Format(linkFormat, startPageIndex.ToString()), startPageIndex.ToString());
                        }
                        startPageIndex++;
                    }

                    int tenCount = totalPage / 10;
                    int remainder = totalPage % 10;

                    startPageIndex = (startPageIndex / 10 + 1) * 10;
                    while (startPageIndex <= totalPage)
                    {
                        pagerLinkBuilder.AppendFormat("<a href=\"{0}\">{1}</a>", string.Format(linkFormat, startPageIndex.ToString()), startPageIndex.ToString());
                        startPageIndex = startPageIndex + 10;
                    }

                    if (remainder != 0)
                    {
                        pagerLinkBuilder.Append("<span>···</span>");
                        pagerLinkBuilder.AppendFormat("<a href=\"{0}\">{1}</a>", string.Format(linkFormat, totalPage.ToString()), totalPage.ToString());
                    }
                }

                //最后10页
                if (pageIndex > totalPage - 5)
                {
                    startPageIndex = totalPage - 9;
                    endPageIndex = totalPage;
                    while (startPageIndex <= endPageIndex)
                    {
                        if (startPageIndex.Equals(pageIndex))
                        {
                            pagerLinkBuilder.AppendFormat("<span class=\"current\">{0}</span>", pageIndex.ToString());
                        }
                        else
                        {
                            pagerLinkBuilder.AppendFormat("<a href=\"{0}\">{1}</a>", string.Format(linkFormat, startPageIndex.ToString()), startPageIndex.ToString());
                        }
                        startPageIndex++;
                    }
                }

            }
            pagerTagBuilder.AddCssClass("pager");
            pagerTagBuilder.InnerHtml = pagerLinkBuilder.ToString();
            pagerTagBuilder.MergeAttributes(htmlAttributes, replaceExisting: true);
            return MvcHtmlString.Create(pagerTagBuilder.ToString(TagRenderMode.Normal));

        }

        public static MvcHtmlString Enum(this HtmlHelper htmlHelper, Enum enumValue)
        {
            return MvcHtmlString.Create(EnumDescriptor.Get(enumValue.GetType())[enumValue.ToString()].Alias);
        }
        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, object model, object propertyList, string textPropertyName, string valuePropertyName, string name = null)
        {
            SelectList selectList = new SelectList((IEnumerable)propertyList, valuePropertyName, textPropertyName);
            IList<SelectListItem> selectListItems = selectList.ToList();

            selectListItems.Insert(0, new SelectListItem { Text = "请选择" });

            if (model != null)
            {
                selectListItems.Single(item => item.Value.Equals(TypeDescriptor.Get(model.GetType()).GetProperty(valuePropertyName).GetValue(model).ToString())).Selected = true;
            }
            if (string.IsNullOrEmpty(name))
            {
                name = valuePropertyName;
            }
            return htmlHelper.DropDownList(name, selectListItems);
        }

        public static MvcHtmlString DropDownListFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression,
            object propertyList, string textPropertyName, string valuePropertyName)
        {
            string name = ExpressionHelper.GetExpressionText(expression);
            object value = htmlHelper.ViewData.Eval(name);
            SelectList selectList = new SelectList((IEnumerable)propertyList, valuePropertyName, textPropertyName);
            if (value != null && !value.GetType().IsValueType && !value.GetType().Equals(typeof(string)))
            {
                ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

                value = metadata.ModelType.GetProperty(valuePropertyName).GetValue(value);
                selectList.Single(option => option.Value.Equals(value)).Selected = true;
            }
            name += "." + valuePropertyName;
            IList<SelectListItem> selectListItems = selectList.ToList();
            selectListItems.Insert(0, new SelectListItem { Text = "请选择" });
            return htmlHelper.DropDownList(name, selectListItems);
        }

        public static MvcHtmlString LoyoutCell(this HtmlHelper html, int width, string htmlString)
        {
            TagBuilder divBuilder = new TagBuilder("div");
            divBuilder.AddCssClass("w" + width.ToString());
            divBuilder.InnerHtml = htmlString;
            return MvcHtmlString.Create(divBuilder.ToString(TagRenderMode.Normal));
        }

        public static MvcHtmlString PropertyCaption(this HtmlHelper html, ModelMetadata metadata, int width)
        {
            string resolvedLabelText = metadata.DisplayName ?? metadata.PropertyName;
            return html.Label(metadata.PropertyName
            , resolvedLabelText, BuildWidthClassAttribute(width));
        }

        public static MvcHtmlString PropertyCaption<TModel, TValue>(this HtmlHelper<TModel> html
         , Expression<Func<TModel, TValue>> expression, int width)
        {
            return html.LabelFor(expression, BuildWidthClassAttribute(width));
        }

        public static MvcHtmlString Property<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, int width)
        {
            if (html.ViewContext.FormContext == null)
            {
                string htmlString = html.LabelFor(expression).ToHtmlString();
                htmlString += html.TextBoxFor(expression, BuildWidthClassAttribute(width)).ToHtmlString();
                html.ValidateFor(expression);
                return MvcHtmlString.Create(htmlString);
            }
            return html.TextBoxFor(expression);
        }

        private static object BuildWidthClassAttribute(int width)
        {
            return new { @class = "w" + width };
        }
        public static MvcHtmlString Submit(this HtmlHelper html, string text, int width)
        {
            TagBuilder submitTagBuilder = new TagBuilder("button");
            submitTagBuilder.Attributes.Add("type", "submit");
            submitTagBuilder.SetInnerText(text);
            return new MvcHtmlString(submitTagBuilder.ToString());
        }
    }
}